#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>

#include "queue.h"
#include "log.h"

#define DEBUG_PRIORITY_FILE  "/debug.log"
#define ERROR_PRIORITY_FILE  "/error.log"
#define WARN_PRIORITY_FILE   "/warn.log"
#define INFO_PRIORITY_FILE   "/info.log"
#define ACCESS_PRIORITY_FILE "/access.log"

static char logdir[FILE_PATH_SIZE];

static FILE *ifp = NULL;
static FILE *wfp = NULL;
static FILE *efp = NULL;
static FILE *dfp = NULL;
static FILE *afp = NULL;

static char* __gettime(char* dest);

static int   __reload_log();

static char* __gettime(char* dest)
{
	time_t rawtime;
	struct tm *newtime;
	time(&rawtime);
	if(NULL == (newtime = localtime(&rawtime)))
	{
		return NULL;
	}
	
	strftime(dest, 20, "%Y-%m-%d %H:%M:%S", newtime);
	return dest;
}

static int __reload_log()
{
	return fini_log() && init_log(logdir);
}

extern int init_log(const char* logpath)
{
	char *ptr;
	char logfile[FILE_PATH_SIZE];	
	if(logpath == NULL)
		snprintf(logdir, FILE_PATH_SIZE, "%s%s", queue_root, QUEUE_DEFAULT_LOG_DIR);
	else if(logpath[0] == '/')
		snprintf(logdir, FILE_PATH_SIZE, "%s", logpath);
	else
		snprintf(logdir, FILE_PATH_SIZE, "%s%s", queue_root, logpath);

	strcpy(logfile, logdir);
	ptr = logfile + strlen(logfile);
	strcpy(ptr, INFO_PRIORITY_FILE);
	if(NULL == (ifp = fopen(logfile, "a+")))
		return -1;
	
	strcpy(ptr, WARN_PRIORITY_FILE);
	if(NULL == (wfp = fopen(logfile, "a+"))){
		fclose(ifp);
		return -1;
	}
	
	strcpy(ptr, ERROR_PRIORITY_FILE);
	if(NULL == (efp = fopen(logfile, "a+"))) {
		fclose(ifp);
		fclose(wfp);
		return -1;
	}
	
	strcpy(ptr, DEBUG_PRIORITY_FILE);
	if(NULL == (dfp = fopen(logfile, "a+"))) {
		fclose(ifp);
		fclose(wfp);
		fclose(efp);
		return -1;
	}
	
	strcpy(ptr, ACCESS_PRIORITY_FILE);
	if(NULL == (afp = fopen(logfile, "a+"))) {
		fclose(ifp);
		fclose(wfp);
		fclose(efp);
		fclose(dfp);
		return -1;
	}

	return 1;
}

int fini_log()
{
	return (fclose(ifp)|fclose(wfp)|
		fclose(efp)|fclose(dfp)|
		fclose(afp)) == 0;
}

int logger(int level, const char* fmt, ...)
{
	FILE *fp;
	char nowtime[20];
	char *format;
	int count = 0;
	int size = 0;
	va_list args;
	
	__gettime(nowtime);
	size = strlen(fmt) + 25;
	format = (char *)malloc(size);
	snprintf(format, size, "[%s] %s\n", nowtime, fmt);
	
 	va_start(args, fmt);
	set_log:
	switch(level)
	{
	case PRIORITY_INFO:
		fp = ifp;	
		break;	
	case PRIORITY_WARN:
		fp = wfp;
		break;	
	case PRIORITY_ERROR:
		fp = efp;
		break;	
	case PRIORITY_DEBUG:
		fp = dfp;
		break;
	case PRIORITY_ACCESS:
		fp = afp;
		break;
	default:
		fp = stderr;
		break;
	}
	
	if(0 > vfprintf(fp, format, args))
	{
		if(2 > count++) {
			__reload_log();
		}
		else
		{
			fp = stderr;
			return -1;
		}
		goto set_log;
	}
	fflush(fp);
	va_end(args);
	free(format);
	return 1;
}

